package com.sans.start;

import org.junit.Test;

import javax.xml.transform.Result;
import java.text.BreakIterator;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;

/**
 * @author Sans
 */
public class ExerciseTest {
    @Test
    public void one() {
        System.out.printf("我叫%s,今年%d岁了,月薪是%.2f元", "Sans", 80, 1234.56);
    }

    @Test
    public void two() {
        System.out.println("[\"\\nlo\\7700\"\']");
    }

    @Test
    public void three() {
        System.out.println("  口口口  口口口  ");
        System.out.println("口      口      口");
        System.out.println("  口          口  ");
        System.out.println("    口      口    ");
        System.out.println("      口  口      ");
        System.out.println("        口        ");
    }

    /**
     * 返回字符串"ABC"中2号位置上的字符。
     */
    @Test
    public void aTest() {
        String str = "ABC";
        char result = str.charAt(2);
        System.out.println(result);
    }

    /**
     * 将"DE"追加到"ABC"末尾。
     */
    @Test
    public void bTest() {
        String str = "ABC";
        String result = str.concat("DE");
        System.out.println(result);
    }

    /**
     * 返回"ABC"中是否包含"AC"。
     */
    @Test
    public void cTest() {
        String str = "ABC";
        boolean result = str.contains("AC");
        System.out.println(result);
    }

    /**
     * 返回"ABC"是否以"BC"结尾。
     */
    @Test
    public void dTest() {
        String str = "ABC";
        boolean result = str.endsWith("BC");
        System.out.println(result);
    }

    /**
     * 返回"ABC"是否以"B"开始。
     */
    @Test
    public void eTest() {
        String str = "ABC";
        boolean result = str.startsWith("B");
        System.out.println(result);
    }

    /**
     * 返回"ABC"是否以"BC"开始。
     */
    @Test
    public void fTest() {
        String str = "ABC";
        boolean result = str.startsWith("BC");
        System.out.println(result);
    }

    /**
     * 返回"ABC"和"abc"是否相等。
     */
    @Test
    public void gTest() {
        String str = "ABC";
        boolean result = str.equals("abc");
        System.out.println(result);
    }

    /**
     * 返回"ABC"和"abc"是否相等，忽略大小写。
     */
    @Test
    public void hTest() {
        String str = "ABC";
        boolean result = str.equalsIgnoreCase("abc");
        System.out.println(result);
    }

    /**
     * 返回"ABC"中，"A"第一次出现的位置。
     */
    @Test
    public void iTest() {
        String str = "ABC";
        int result = str.indexOf("A");
        System.out.println(result);
    }

    /**
     * 返回"ABC"中，"A"第一次出现的位置，（从1号位开始查找）。
     */
    @Test
    public void jTest() {
        String str = "ABC";
        int result = str.indexOf("A", 1);
        System.out.println(result);
    }

    /**
     * 返回"ABC"中，"A"最后一次出现的位置。
     */
    @Test
    public void kTest() {
        String str = "ABC";
        int result = str.lastIndexOf("A");
        System.out.println(result);
    }

    /**
     * 返回"ABC"中，"A"最后一次出现的位置，（从1号位开始查找）。
     */
    @Test
    public void lTest() {
        String str = "ABC";
        int result = str.lastIndexOf("A", 1);
        System.out.println(result);
    }

    /**
     * 返回""是否是空字符串。
     */
    @Test
    public void mTest() {
        String str = "";
        boolean result = str.isEmpty();
        System.out.println(result);
    }

    /**
     * 返回"林JUNJIE"有多少个字节。
     */
    @Test
    public void nTest() {
        String str = "林JUNJIE";
        int result = str.length();
        System.out.println(result);
    }

    /**
     * 返回将"ABCA"中的所有"A"都替换成"a"之后的字符串。
     */
    @Test
    public void oTest() {
        String str = "ABCA";
        String result = str.replace("A", "a");
        System.out.println(result);
    }

    /**
     * 返回"ABCD"中2号位之后（包括2号位）的字符串。
     */
    @Test
    public void pTest() {
        String str = "ABCD";
        String result = str.substring(2);
        System.out.println(result);
    }

    /**
     * 返回"ABCD"中1号位（包括1号位）和2号位之间的字符串。
     */
    @Test
    public void qTest() {
        String str = "ABCD";
        String result = str.substring(1, 2);
        System.out.println(result);
    }

    /**
     * 返回"ABCD"转成小写之后的字符串。
     */
    @Test
    public void rTest() {
        String str = "ABCD";
        String result = str.toLowerCase();
        System.out.println(result);
    }

    /**
     * 返回"abcd"转成大写之后的字符串。
     */
    @Test
    public void sTest() {
        String str = "abcd";
        String result = str.toUpperCase();
        System.out.println(result);
    }

    /**
     * 返回" abcd "两端去空格之后的字符串。
     */
    @Test
    public void tTest() {
        String str = " abcd ";
        String result = str.trim();
        System.out.println(result);
    }

    /**
     * 返回以"我叫%s，今年%d岁了，月薪%.2f元"为模板的格式化输出内容。
     */
    @Test
    public void uTest() {
        String str = "我叫%s，今年%d岁了，月薪%.2f元";
        String result = String.format(str, "古尔丹", 103, 37524.65);
        System.out.println(result);
    }

    /**
     * 返回将一个布尔类型的true转换为字符串"true"的结果。
     */
    @Test
    public void vTest() {
        String result = String.valueOf(true);
        System.out.println(result);
    }

    /**
     * 字符串"abcabcabc"，查找第一个a和最后一个a的位置。
     */
    @Test
    public void wTest() {
        String str = "abcabcabc";
        int result1 = str.indexOf("a");
        int result2 = str.lastIndexOf("b");
        System.out.println(result1);
        System.out.println(result2);
    }

    /**
     * 字符串"abcabcabc"，查找第二个b的位置。
     */
    @Test
    public void xTest() {
        String str = "abcabcabc";
        int result1 = str.indexOf("b");
        int result = str.indexOf("b", result1 + 1);
        System.out.println(result);
    }

    /**
     * 字符串"abcabcabc"，判断是否只有一个a。
     */
    @Test
    public void yTest() {
        String str = "abcabcabc";
        System.out.println(str.indexOf("a") == str.lastIndexOf("a"));
    }

    /**
     * 字符串"abc abc abc"，删除所有的空格之后，截取第一个b和最后一个b中间的内容。
     */
    @Test
    public void zTest() {
        String str = "abc abc abc";
        String result1 = str.replace(" ", "");
        int str1 = result1.indexOf("b");
        int str2 = result1.lastIndexOf("b");
        String result = result1.substring(str1 + 1, str2);
        System.out.println(result);
    }

    /**
     * 字符串" abc ABCabc "，去掉两端的空格之后，将字符串中的所有字母，都转成小写形式。
     */
    @Test
    public void test0() {
        String str = " abc ABCabc ";
        String result1 = str.trim();
        String result = result1.toLowerCase();
        System.out.println(result);
    }

    /**
     * What is the result?
     */
    @Test
    public void test1() {
        int a = 13, b = 3;
        System.out.println(++a + b);
        System.out.println(a-- - b);
        System.out.println(a);
        System.out.println(b);
    }

    /**
     * What is the result?
     */
    @Test
    public void test2() {
        int a = 1;
        System.out.println(++a + a++ + a++ + a);
        System.out.println(a);
    }

    /**
     * 会溢出吗?
     */
    @Test
    public void test3() {
        long result = 2147483647 + 1;
        System.out.println(result);
    }

    /**
     * What is the result?
     */
    @Test
    public void test4() {
        int a = 13, b = 3;
        System.out.println(a += b);
        System.out.println(a -= b);
        System.out.println(a *= b);
        System.out.println(a /= b);
        System.out.println(a %= b);
    }

    /**
     * What is the result?
     */
    @Test
    public void test5() {
        int a = 10;
        System.out.println(a %= 11);
    }

    /**
     * What is the result?
     */
    @Test
    public void test6() {
        int a = 10;
        System.out.println(a /= 10 + 6);
    }

    /**
     * What is the result?
     */
    @Test
    public void test7() {
        System.out.println(1 == 2 == true);
    }

    /**
     * What is the result?
     */
    @Test
    public void test8() {
        System.out.println(false && true);
        System.out.println(true || false);
        System.out.println(true || false && false || true);
        System.out.println(true || false && false || false);
    }

    /**
     * What is the result?
     */
    @Test
    public void test9() {
        int a = 1;
        System.out.println(1 == 2 && a++ == 2);
        System.out.println(a);
    }

    /**
     * 现有int a=1, b=2，请交换这两个变量的值。
     */
    @Test
    public void test10() {
        int a = 1, b = 2;
        a += b;
        b = a - b;
        a -= b;
        System.out.println(a);
        System.out.println(b);
    }

    /**
     * 利用三目运算符，如果分数小于0,分数有问题，如果分数在0-60之间，显示不及格，
     * 如果分数在61-80之间，显示及格，如果分数在81-100之间，显示优秀，如果分数在100以上，
     * 显示分数有问题
     */
    @Test
    public void test11() {
        int score = 59;
        String result = (score > 100 || score < 0) ? "分数有问题" : (score >= 80 ? "优秀" : (score >= 60 ? "及格" : "不及格"));
        System.out.println(result);
    }

    /**
     * 请使用三目运算符编写一个"两数比大小程序"，要求有 "大"， "小"，和 "相等" 三种结果。
     */
    @Test
    public void test12() {
        int a = 9, b = 7;
        String result = a == b ? "相等" : (a > b ? "大" : "小");
        System.out.println(result);
    }

    /**
     * 请使用三目运算符编写一个"两数比大小程序"，谁大输出谁，相等输出 "相等"。
     */
    @Test
    public void test13() {
        int a = 7, b = 7;
        String result = a == b ? "相等" : (a > b ? String.valueOf(a) : "" + b);
        System.out.println(result);
    }

    @Test
    public void test14() {
        Random random = new Random();
        System.out.println(random.nextInt(5) + 5);
        System.out.println(random.nextInt(5) + 5);
        System.out.println(random.nextInt(5) + 5);
        System.out.println(random.nextInt(5) + 5);
        System.out.println(random.nextInt(5) + 5);
    }

    /**
     * 如果你不给我一百万，我是不会嫁给你的！
     */
    @Test
    public void test15() {
        int money = new Random().nextInt(2000001);
        System.out.println("存款:" + money);
        if (money >= 1000000) {
            System.out.println("土豪，我要嫁给你!!!");
        } else {
            System.out.println("穷逼，你也配???");
        }
    }

    /**
     * 山无棱，天地合，才敢与君绝！
     */
    @Test
    public void test16() {
        String str1 = "山无棱";
        String str2 = "天地不合";
        if (str1 == "山无棱") {
            if (str2 == "天地合") {
                System.out.println("山无棱，天地合，才敢与君绝！");
            } else {
                System.out.println("不敢与君绝！");
            }
        } else {
            System.out.println("不敢与君绝！");
        }
    }

    /**
     * 定义一个年龄，年龄在0-100岁之间，如果小于100岁为老年，小于50岁为中年，小于30岁为青年，小于16岁为儿童。
     */
    @Test
    public void test17() {
        int age = new Random().nextInt(111);
        System.out.println("年龄:" + age);
        if (age < 16) {
            System.out.println("你是儿童...");
        } else if (age < 30) {
            System.out.println("你是青年人...");
        } else if (age < 50) {
            System.out.println("你是中年人...");
        } else if (age < 100) {
            System.out.println("你是老年人...");
        } else {
            System.out.println("你不是人...");
        }
    }

    /**
     * What is the result?
     * A. 2
     * B. 3
     * C. 1 2
     * D. 2 3
     * E. 1 2 3
     * F. Compilation fails.
     * G. An exception is thrown at runtime.
     *
     *public class Test {
     *     public static void main(String [] args) {
     *         int x = 5;
     *         boolean b1 = true;
     *         boolean b2 = false;
     *         if ((x == 4) && !b2 )
     *         System.out.print("1 ");
     *         System.out.print("2 ");
     *         if ((b2 = true) && b1 );
     *         System.out.print("3 ");
     *     }
     * }
     */

    /**
     * 指定一个图书编号，01代表红楼梦，02代表西游记，03代表金瓶梅，04代表水浒传，对应编号输出。
     */
    @Test
    public void test18() {
        int num = new Random().nextInt(4);
        System.out.println("编号:0" + (num + 1));
        switch ("0" + (num + 1)) {
            case "01":
                System.out.println("红楼梦");
                break;
            case "02":
                System.out.println("西游记");
                break;
            case "03":
                System.out.println("金瓶梅");
                break;
            case "04":
                System.out.println("水浒传");
                break;
            default:
                System.out.println("没有这本书");
        }
    }

    /**
     * 指定一个分数，60分以下不及格，60-80之间及格，80-100优秀，要求只能使用switch。
     */
    @Test
    public void test19() {
        int n = new Random().nextInt(101);
        System.out.println("分数:" + n);
        int score = n / 20;
        switch (score) {
            case 0:
            case 1:
            case 2:
                System.out.println("不及格");
                break;
            case 3:
                System.out.println("及格");
                break;
            case 4:
                System.out.println("优秀");
                break;
            default:
                System.out.println("分数有问题");
                break;
        }
    }

    /**
     * 输出数字串"18210210122"中的最大数字"8"和最小值数字"0"
     */
    @Test
    public void test20() {
        String str = "18210210122";
        char[] chars = str.toCharArray();
        Arrays.sort(chars);
        System.out.println("最小数字:" + chars[0]);
        System.out.println("最大数字:" + chars[chars.length - 1]);
    }

    /**
     * 找出2个已知数组中相同的值：
     * int[] as = {2, 3, 6, 9, 11, 15, 19, 23, 35};
     * int[] bs = {1, 3, 7, 9, 11, 13, 14, 19, 35};
     */
    @Test
    public void test21() {
        int[] as = {2, 3, 6, 9, 11, 15, 19, 23, 35};
        int[] bs = {1, 3, 7, 9, 11, 13, 14, 19, 35};
        Stack<Integer> stack = new Stack<>();
        for (int i = 0, j = as.length; i < j; i++) {
            for (int m = 0, n = bs.length; m < n; m++) {
                if (as[i] == bs[m]) {
                    stack.push(as[i]);
                }
            }
        }
        System.out.println("相同的数:" + stack);
    }

    /**
     * 设计程序，要求可以从1到32随机生成不重复的7个数。
     */
    @Test
    public void test22() {
        int[] num = new int[32];
        Random random = new Random();
        int flag = 0;
        for (int i = 0; i < 32; i++) {
            num[i] = i + 1;
        }
        while (flag < 10000) {
            int x = random.nextInt(32);
            int y = random.nextInt(32);
            int z = num[x];
            num[x] = num[y];
            num[y] = z;
            flag++;
        }
        for (int j = 0; j < 7; j++) {
            System.out.println(num[j]);
        }
    }

    /**
     * 某公司按照季度和月份统计的数据如下，单位（万元）
     * <p>
     * 第一季度：22, 66, 44
     * 第二季度：77, 33, 88
     * 第三季度：25, 45, 65
     * 第四季度：11, 66, 99
     * 求公司年度销售总额是多少?
     */
    @Test
    public void test23() {
        int sum = 0;
        int[][] arrA = {
                {22, 66, 44},
                {77, 33, 88},
                {25, 45, 65},
                {11, 66, 99}
        };
        for (int i = 0; i < 4; i++) {
            for (int j = 0; j < 3; j++) {
                sum += arrA[i][j];
            }
        }
        System.out.println(sum);
    }

    /**
     * 逢三必杀
     */
    @Test
    public void test24() {
        int[] num = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};
        //数数
        int flag = 0;
        //数零
        int zero = 0;
        while (zero != num.length - 1) {
            for (int i = 0; i < num.length; i++) {
                if (num[i] != 0) {
                    flag++;
                    if (flag % 3 == 0) {
                        num[i] = 0;
                        zero++;
                    }
                }
            }
        }
        for (int e : num) {
            if (e != 0) {
                System.out.println(e);
            }
        }
    }

    /**
     * 逢三必杀 2.0
     */
    @Test
    public void test25() {
        Queue<Integer> queue = new LinkedBlockingQueue<>();
        for (int i = 0; i < 10; i++) {
            queue.add(i + 1);
        }
        System.out.println(queue);
        while (queue.size() != 1) {
            queue.add(queue.poll());
            queue.add(queue.poll());
            queue.poll();
            System.out.println(queue);

        }
    }

    /**
     * 斐波那契数列
     */
    @Test
    public void test26() {
        int[] num = new int[20];
        num[0] = 0;
        num[1] = 1;
        for (int i = 2; i < 20; i++) {
            num[i] = num[i - 1] + num[i - 2];
        }
        for (int e : num) {
            System.out.print(e + " ");
        }
    }

    /**
     * 梅花桩
     */
    @Test
    public void test27() {
        int flag = 0;
        Queue<Integer> queue = new LinkedBlockingQueue<>();
        for (int i = 2; i < 9; i++) {
            queue.add(i);
        }
        while (flag != 49) {
            queue.add(9 - queue.poll());
            flag++;
        }
        System.out.println(queue.peek());
    }

    /**
     * 梅花桩 2.0
     */
    @Test
    public void test28() {
        int zNO = 1;
        boolean flag = false;
        for (int i = 0; i < 50; i++) {
            if (zNO == 1 || zNO == 8) {
                flag = !flag;
            }
            zNO = flag ? zNO + 1 : zNO - 1;
        }
        System.out.println(zNO);
    }

    /**
     * 拆读数字（三位数），例如：153翻译成一百五十三。
     */
    @Test
    public void test29() {
        int num = 153;
        String[] str = {"零", "一", "二", "三", "四", "五", "六", "七", "八", "九"};
        //百位
        int x = num / 100;
        //十位
        int y = num / 10 % 10;
        //个位
        int z = num % 10;
        if (y == 0) {
            if (z == 0) {
                System.out.println(str[x] + "百");
            } else {
                System.out.println(str[x] + "百零" + str[z]);
            }
        } else if (z == 0) {
            System.out.println(str[x] + "百" + str[y]);
        } else {
            System.out.println(str[x] + "百" + str[y] + "百" + str[z]);
        }
    }

    /**
     * 打印1-2000之间既能被3整除又能被8整除的前15个数，逢5换行。
     */
    @Test
    public void test30() {
        int flag = 0;
        for (int i = 1; i <= 2000; i++) {
            if (i % 3 == 0 && i % 8 == 0) {
                System.out.print(i + " ");
                flag++;
                if (flag % 5 == 0) {
                    System.out.println();
                }
                if (flag == 15) {
                    break;
                }
            }
        }
    }

    /**
     * 编写程序算出1！+2！+3！+ … +10！的和。（3！标识1*2*3）
     */
    @Test
    public void test31() {
        long sum = 1;
        long num = 1;
        for (int i = 10; i > 1; i--) {
            for (int j = i; j > 0; j--) {
                num *= j;
            }
            sum += num;
            num = 1;
        }
        System.out.println(sum);
    }

    /**
     * 判断101-200之间有多少个素数，并输出所有素数，除了1和本身不能被任何数整除的数叫素数。
     */
    @Test
    public void test32() {
        int flag = 0;
        for (int i = 101; i <= 200; i++) {
            for (int j = i - 1; j > 1; j--) {
                if (i % j == 0) {
                    break;
                } else if (j == 2) {
                    flag++;
                    System.out.print(i + " ");
                }
            }
        }
        System.out.println();
        System.out.println("共有" + flag + "个素数...");
    }

    /**
     * 打印100-1000的水仙花数，水仙花数：其各位置上的数字的立方和等于该数字本身。
     */
    @Test
    public void test33() {
        int num;
        for (num = 100; num < 1000; num++) {
            int x = num / 100;
            int y = num / 10 % 10;
            int z = num % 10;
            if (x * x * x + y * y * y + z * z * z == num) {
                System.out.print(num + " ");
            }
        }
    }

    /**
     * 打印10行杨辉三角（每个数等于它上面的数加上它上面的左边的数）。
     * 1
     * 1 1
     * 1 2 1
     * 1 3 3 1
     * 1 4 6 4 1
     */
    @Test
    public void test34() {
        int[] num1 = new int[10];
        int[] num2 = new int[10];
        for (int i = 1; i <= 10; i++) {
            for (int j = 0; j < i; j++) {
                if (j == 0 || j == i - 1) {
                    num1[j] = 1;
                    System.out.print(num1[j] + " ");
                } else {
                    num1[j] = num2[j] + num2[j - 1];
                    System.out.print(num1[j] + " ");
                }
            }
            System.out.println();
            System.arraycopy(num1, 0, num2, 0, i);
        }
    }

    /**
     * 部门编号 | 部门名 | 地址
     * ---|---|---
     * 10 | ACCOUNTING | NEW YORK
     * 20 | RESEARCH   | DALLAS
     * 30 | SALES      | CHICAGO
     * 40 | OPERATIONS | BOSTON
     * <p>
     * - 将每条部门信息放入独立的Map对象中；
     * - 将这些Map对象放入List对象中；
     * - 在List中找到部门编号为10的部门所在的Map对象，将部门名改为软件部；
     * - 从List中遍历出每一个部门信息每条信息显示结果为: ACCOUNTING(编号:10,地址:NEW YORK)
     */
    @Test
    public void test35() {
        Map<String, Object> map1 = new HashMap<>(10);
        Map<String, Object> map2 = new HashMap<>(10);
        Map<String, Object> map3 = new HashMap<>(10);
        Map<String, Object> map4 = new HashMap<>(10);
        Map<String, Object> map5 = new HashMap<>(10);
        map1.put("部门编号", 10);
        map1.put("部门名", "ACCOUNTING");
        map1.put("地址", "NEW YORK");
        map2.put("部门编号", 20);
        map2.put("部门名", "RESEARCH");
        map2.put("地址", "DALLAS");
        map3.put("部门编号", 30);
        map3.put("部门名", "SALES");
        map3.put("地址", "CHICAGO");
        map4.put("部门编号", 40);
        map4.put("部门名", "OPERATIONS");
        map4.put("地址", "BOSTON");
        List<Object> list = List.of(map1, map2, map3, map4);
        for (int i = 0, j = list.size(); i < j; i++) {
            map5 = (Map<String, Object>) list.get(i);
            if (map5.containsValue(10)) {
                map5.replace("部门名", "软件部");
            }
            Object num = map5.get("部门编号");
            Object dpm = map5.get("部门名");
            Object ads = map5.get("地址");
            System.out.println(dpm + "(编号：" + num + ",地址：" + ads + ")");
        }
    }

    /**
     * 求字符串 "aabawebaaabbeecc" 中，各个字母出现的次数，如a出现2次，b出现1次。
     * - 将字符串转换成字符数组。
     * - 定义一个空HashMap。
     * - 遍历字符数组。
     * - 将每一个字母作为键去Map集合获取。
     * - 如果返回null，说明Map中还没有这个字母，则可以将该字母和1存入Map。
     * - 如果返回不是null，说明该字母在Map中已经存在，且有了对应次数，那么就获取该次数进行自增，然后将该字母和自增后的次数存入Map。
     * - 遍历Map
     */
    @Test
    public void test36() {
        String str = "aabawebaaabbeecc";
        char[] ch = str.toCharArray();
        Map<Character, Integer> map = new HashMap<>(20);
        Set<Map.Entry<Character, Integer>> entries = map.entrySet();
        for (int i = 0, j = ch.length; i < j; i++) {
            if (map.get(ch[i]) == null) {
                map.put(ch[i],1);
            } else {
                map.replace(ch[i],map.get(ch[i])+1);
            }
        }
        for (Map.Entry<Character, Integer> e : entries) {
            System.out.println(e.getKey() + ":" + e.getValue());
        }
    }
}